
/* <<< COPYRIGHT START >>>
 * Copyright 2006-Present OxygenSoftwareLibrary.com
 * Licensed under the GNU Lesser General Public License.
 * http://www.gnu.org/licenses/lgpl.html
 * 
 * @author: Ugorji Dick-Nwoke
 * <<< COPYRIGHT END >>>
 */


package oxygen.forum;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Properties;
import java.util.Timer;

import oxygen.forum.data.ForumDAO;
import oxygen.manager.GroupManager;
import oxygen.manager.UserPasswordManager;
import oxygen.manager.UserPreferencesManager;
import oxygen.markup.MarkupConstants;
import oxygen.markup.MarkupContainerEngine;
import oxygen.markup.MarkupParserFactory;
import oxygen.util.CloseUtils;
import oxygen.util.OxygenUtils;
import oxygen.util.PluginManager;
import oxygen.util.SimpleLock;
import oxygen.web.ActionManager;
import oxygen.web.I18nManager;
import oxygen.web.WebLocal;

public class ForumEngine extends MarkupContainerEngine {
  
  private ForumDAO dao;
  private ForumIndexingManager indexMgr;
  private ForumEventManager eventMgr;
  private ForumStatisticsManager statsMgr;
  private ForumRenderEngine renderEngine;
  private ForumPruneManager pruneMgr;
  
  /* package */ 
  ForumEngine() throws Exception {
    this(new Properties());
  }
  
  /* package */ 
  ForumEngine(Properties p) throws Exception {
    OxygenUtils.info("ForumEngine initialization starting ...");
    long lcurr = System.currentTimeMillis();
    try {
      ForumLocal.setForumEngine(this);
      WebLocal.setOxygenContainerEngine(this);
      props = new Properties();
      reinit(p);
    } finally {
      ForumLocal.setForumEngine(null);
      WebLocal.setOxygenContainerEngine(null);
    }
    OxygenUtils.info("ForumEngine initialization completed in " + (System.currentTimeMillis() - lcurr) + " ms");
  }
  
  public ForumIndexingManager getForumIndexingManager() {
    return indexMgr;
  }
  
  public ForumDAO getForumDAO() {
    return dao;
  }
  
  public ForumEventManager getForumEventManager() {
    return eventMgr;
  }
  
  public ForumStatisticsManager getForumStatisticsManager() {
    return statsMgr;
  }
  
  public ForumRenderEngine getForumRenderEngine() {
    return renderEngine;
  }
  
  public ForumPruneManager getForumPruneManager() {
    return pruneMgr;
  }
  
  public void close() {
    OxygenUtils.info("ForumEngine closing ...");
    long lcurr = System.currentTimeMillis();
    CloseUtils.close(postInitPluginMgr);
    props.clear();
    CloseUtils.close(dao);
    CloseUtils.close(authMgr);
    CloseUtils.close(prefsMgr);
    CloseUtils.close(atzMgr);
    CloseUtils.close(i18n);
    CloseUtils.close(actionMgr);
    CloseUtils.close(templateHdlr);
    //CloseUtils.close(indexMgr);
    //CloseUtils.close(eventMgr);
    CloseUtils.close(statsMgr);
    CloseUtils.close(renderEngine);
    //CloseUtils.close(pruneMgr);
    CloseUtils.close(preInitPluginMgr);
    CloseUtils.close(shortTermAcquiredLock);
    CloseUtils.close(longTermLock);
    int initTimeSecs = (int)((System.currentTimeMillis() - lcurr) / 1000);
    OxygenUtils.info("ForumEngine is closed in " + initTimeSecs + " seconds");
  }
    

  public boolean isUsernameOverrideAllowed() {
    return "true".equals(getProperty(ForumConstants.ALLOW_OVERRIDE_USERNAME_KEY));
  }
  
  private void reinit(Properties initProps0) throws Exception {
    //System.out.println("Integer.MAX_VALUE: " + Integer.MAX_VALUE);
    if(initProps0 != null) {
      //should we pass in the initProps0 as the parent of props? FIXME
      props.putAll(initProps0);
    }
    ClassLoader cl = Thread.currentThread().getContextClassLoader();
    InputStream is = cl.getResourceAsStream("oxygen/forum/init.properties");
    props.load(is);
    CloseUtils.close(is);
    is = cl.getResourceAsStream(ForumConstants.CONFIG_INIT_OVERRIDE_FILE);
    if(is != null) {
      props.load(is);
      CloseUtils.close(is);
    }
    
    File f = new File(getConfigDirectory(), "oxyforum.properties");
    if(f.exists()) {
      is = new FileInputStream(f);
      props.load(is);
      CloseUtils.close(is);
    }    
    
    timer = new Timer(true);
        
    String s = null;
    
    s = getProperty(MarkupConstants.PARSER_FACTORY_CLASS_KEY);
    markupParserFactory = (MarkupParserFactory)Class.forName(s).newInstance();
    
    preInitPluginMgr = new PluginManager(props, "oxygen.forum.plugin.preinit.");
    preInitPluginMgr.start();
    
    actionMgr = new ActionManager(props, "oxygen.forum.action.");
    i18n = new I18nManager("oxygen.forum.Forum");
    templateHdlr = new ForumTemplateHandler();
    
    s = getProperty(ForumConstants.AUTHENTICATION_MANAGER_KEY);
    authMgr = (UserPasswordManager)Class.forName(s).newInstance();
    authMgr.init(props);
    
    s = getProperty(ForumConstants.AUTHORIZATION_MANAGER_KEY);
    atzMgr = (GroupManager)Class.forName(s).newInstance();
    atzMgr.init(props);
    
    s = getProperty(ForumConstants.USERPREFERENCES_MANAGER_KEY);
    prefsMgr = (UserPreferencesManager)Class.forName(s).newInstance();
    prefsMgr.init(props);
    
    dao = new ForumDAO();

    statsMgr = new ForumStatisticsManager();

    indexMgr = new ForumIndexingManager();

    renderEngine = new ForumRenderEngine();

    pruneMgr = new ForumPruneManager();
    
    eventMgr = new ForumEventManager();
    
    postInitPluginMgr = new PluginManager(props, "oxygen.forum.plugin.postinit.");
    postInitPluginMgr.start();

    longTermLock = new SimpleLock();
    shortTermAcquiredLock = new SimpleLock.Strict();
  }
  
}

